# 构建用户画像
from collections import OrderedDict
import io
import csv
import json
import sys
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from py2neo import Graph
import redis
from bulid_distance import city_similarity, read_cities_data, get_ex_cities

sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')


class UserProfile:
    def __init__(self, skills, city, salary):
        self.skills = skills
        self.city = city
        self.salary = salary


# 连接到 Redis 服务器
redis_client = redis.StrictRedis(host='8.140.243.61', port=6210, db=0)


def get_recommendations_from_cache(userName):
    # 构建带有用户标识的缓存键
    cache_key = f'user:{userName}:job_results'
    # 从 Redis 获取数据
    job_results = redis_client.get(cache_key)
    if job_results:
        return job_results.decode('utf-8')  # 返回缓存数据

    return None  # 返回空表示缓存不存在或已过期


# 从redis缓存中获取推荐工作数据
# def get_recommendations_from_cache():
#     # 从 Redis 获取数据
#     job_results = redis_client.get('job_results')
#     if job_results:
#         return job_results.decode('utf-8')  # 返回缓存数据
#     else:
#         return None  # 返回空表示缓存不存在或已过期


def recommend_positions(user_profile, userName):
    global job_result_dict, redis_client
    cached_data = get_recommendations_from_cache(userName)

    if cached_data:
        return cached_data  # 直接返回缓存中的推荐数据
    else:
        citycsv = open('data/job.csv', 'r', encoding="utf-8")
        cityreader = csv.reader(citycsv)
        jobData = list(cityreader)
        graph = Graph("http://localhost:7474", auth=("neo4j", "Xiyou666"), name="neo4j")
        expected_city = user_profile.city
        expected_salary1 = user_profile.salary
        expected_skills = user_profile.skills
        skills_list = expected_skills.split(',')
        skills = [s.strip() for s in skills_list]
        user_skills = {"skills": ','.join(skills)}
        exCity = set()
        jobCity = get_ex_cities(expected_city)
        citySimilarities = city_similarity(expected_city, jobCity)
        for city_name, similarity in citySimilarities:
            exCity.add(city_name)
        # print(list(exCity))
        job_result = []
        for i in range(1, len(jobData)):
            results = []
            query = '''
                MATCH (j:job {id: $id})-[:HAS_SALARY]->(s:Salary),
                      (j)-[:LOCATED_IN]->(c:City),
                      (j)-[:REQUIRES]->(sk:skills)
                WHERE s.salary >= $expected_salary AND c.name IN $city
                RETURN s, c, COLLECT(sk) AS skills, j.id
            '''
            # 执行查询并传入参数
            result_category = graph.run(query, id=jobData[i][0], expected_salary=float(expected_salary1),
                                        city=list(exCity)).data()
            # print(result_category)
            if result_category:
                for result in result_category:
                    salary = result['s']['salary']
                    city = result['c']['name']
                    skills = [skill['name'] for skill in result['skills']]
                    jobId = result['j.id']
                    skill = ','.join(skills)
                    job_skills = {"skills": skill}

                    # 将技能转换为向量
                    vectorizer = CountVectorizer(tokenizer=lambda x: x.split(','))
                    job_vector = vectorizer.fit_transform([job_skills["skills"]])
                    user_vector = vectorizer.transform([user_skills["skills"]])

                    # 计算余弦相似度
                    similarity = cosine_similarity(user_vector, job_vector)
                    if similarity > 0.4:
                        # 将结果添加到列表中
                        results.append(
                            {"similarity": similarity, "jobId": jobId, "salary": salary, "city": city,
                             "skills": skills})

                        # 按照相似度从大到小进行排序
                        results.sort(key=lambda x: x["similarity"], reverse=True)
                        # 打印结果
                        for result1 in results:
                            # print(
                            #     "____________________________________________________________________________________________________________________________________")
                            # print(f"JobId: {result1['jobId']}")
                            # print(f"Salary: {result1['salary']}")
                            # print(f"City: {result1['city']}")
                            # print(f"Skills: {result1['skills']}")
                            # print(f"相似度: {result1['similarity']}")
                            query2 = '''
                               MATCH (j:job {id: $jobId})
                               RETURN j
                           '''
                            # 执行查询并传入参数
                            result = graph.run(query2, jobId=result1['jobId']).data()
                            job_result.extend(result)
        # print(job_result)
        # # 将结果转换为字典格式
        # job_result_list = []
        # for result in job_result:
        #     job_result_dict = {}
        #     job_result_dict.update(result)
        #     job_result_list.append(job_result_dict)
        # print(job_result_dict)

        result_dict = []
        for result in job_result:
            job_dict = {
                "id": result['j']['id'],
                "company": result['j']['company'],
                "title": result['j']['name'],
                "salary": result['j']['salary'],
                "education": result['j']['education'],
                "description": result['j']['description'],
                "hiring_manager": result['j']['hiring_manager'],
                "last_active": result['j']['last_active'],
                "address": result['j']['address'],
                "link": result['j']['link'],
            }
            result_dict.append(job_dict)
        # print(result_dict)
        json_str = json.dumps(result_dict, ensure_ascii=False)
        # # 将数据转换为 JSON 格式（假设 result_category 是一个列表）
        # result_json = json.dumps(result)

        # 将数据存储到 Redis 中，设置过期时间为 3600 秒（1 小时）
        cache_key = f'user:{userName}:job_results'
        redis_client.set(cache_key, json_str)
        redis_client.expire(cache_key, 3600)
        # print(json_str)
        return json_str


# # 获取推荐
# recommended_positions = recommend_positions(user_profile, knowledge_graph)

if __name__ == '__main__':
    arguments = ''
    # 打印传递的参数
    if len(sys.argv) > 1:
        for arg in sys.argv[1:]:
            arguments = ' '.join(sys.argv[1:])
    # print(arguments)
    # 分割字符串，从后面开始
    fields = arguments.split(',')
    # 提取字段
    userName = fields[0]
    salary = float(fields[-1])
    city = fields[1]
    skills = ','.join(fields[2:-1])
    user_profile = UserProfile(skills, city, salary)
    # user_profile = UserProfile('java', '成都市', 5000.0)
    # print(user_profile.skills)
    # print(user_profile.city)
    # print(user_profile.salary)
    # print(userName)
    json = recommend_positions(user_profile, userName)
    print(json)
